package api

import (
	"TaskAssignmentSystem/internal/app/dao"
	"TaskAssignmentSystem/internal/app/services"
	"TaskAssignmentSystem/internal/pkg/middleware/handler"
	"TaskAssignmentSystem/internal/pkg/modelbase"
	"TaskAssignmentSystem/pkg/db/redis"
	"TaskAssignmentSystem/pkg/timehandler"
	"TaskAssignmentSystem/pkg/utils"
	"fmt"
	"github.com/golang/glog"
	"github.com/kataras/iris/v12"
	"time"
)

type GiveUpTopicRequest struct {
	Id      uint     `json:"id"`
	Reason  string   `json:"reason"`
	OssPath []string `json:"oss_path"`
}

// @Summary 放弃题目
// @Description 放弃题目
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body GiveUpTopicRequest true "放弃题目参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/topic/give_up [post]
func GiveUpTopicHandler(ctx iris.Context) {
	var RequestParams GiveUpTopicRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var clams = services.CustomClaims{}
	if err := clams.ParseClaims(ctx); err != nil {
		glog.Infoln("用户%s,放弃题目 %d", clams.UserName, RequestParams.Id)
	}

	var topicServe services.TopicService
	if err := topicServe.GiveUpTopic(RequestParams.Id, clams.Id, RequestParams.Reason, RequestParams.OssPath); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type RepairListRequest struct {
	ProjectId string `json:"project_id"`
}

// @Summary 返修题目列表
// @Description 返修题目列表
// @Tags 题目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body RepairListRequest true "返修题目列表参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/topic/repair/list [post]
func RepairTopicHandler(ctx iris.Context) {
	var RequestParams RepairListRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	// 查询当前项目的详情
	var projectDao dao.Common[dao.SystemProject]
	projectDao.Query = map[string]interface{}{"project_id": RequestParams.ProjectId}
	projectDO, err := projectDao.First(projectDao.Query)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var topicDao services.CommonService[dao.SystemTopic]
	topicDao.Page = 1
	topicDao.PageSize = 1000
	//过滤条件 当前项目 绑定关系为当前用户的user_id 状态为返修的状态 4 题目作废阀值不能小于1
	topicDao.Query = map[string]interface{}{"project_id": RequestParams.ProjectId, "receiver_id": claims.UserName, "status": 4}
	topicDao.WhereStr = append(topicDao.WhereStr, fmt.Sprintf("give_up_number >= 1 "))
	topicDao.WhereStr = append(topicDao.WhereStr, fmt.Sprintf("finish_time > now() "))
	topicDao.Order = "sn"
	if res, err := topicDao.SelectList(); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		// 返修题目视角
		if projectDO.EnumType == modelbase.WorkProj {
			// 查询原题以及作答
			topicVOList := batchQueryTopicAnswerVO(projectDO.ProjectId, res.Data)
			// 查询一审和二审审核内容
			if utils.StringIsNotEmpty(projectDO.AuditProjectId) || utils.StringIsNotEmpty(projectDO.FinalProjectId) {
				//一审二审都有内容
				if utils.StringIsNotEmpty(projectDO.AuditProjectId) && utils.StringIsNotEmpty(projectDO.FinalProjectId) {
					topicOneAuditVOList := batchQueryTopicAnswerVO(projectDO.AuditProjectId, res.Data)
					auditmapOne := batchQueryTopicAudit(res.Data)
					for i, topic := range topicOneAuditVOList {
						topicOneAuditVOList[i].TopicAudit = auditmapOne[topic.TopicId]
						topic.TopicAudit = auditmapOne[topic.TopicId]
					}

					topicTwoAuditVOList := batchQueryTopicAnswerVO(projectDO.FinalProjectId, res.Data)
					auditmapTwo := batchQueryTopicAudit(res.Data)
					for i, topic := range topicTwoAuditVOList {
						topicTwoAuditVOList[i].TopicAudit = auditmapTwo[topic.TopicId]
						topic.TopicAudit = auditmapTwo[topic.TopicId]
					}
					ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_one_list": topicOneAuditVOList, "topic_audit_two_list": topicTwoAuditVOList}})
					return
				} else if utils.StringIsNotEmpty(projectDO.AuditProjectId) && utils.StringIsEmpty(projectDO.FinalProjectId) {
					//只有一审有内容
					topicOneAuditVOList := batchQueryTopicAnswerVO(projectDO.AuditProjectId, res.Data)
					auditmapOne := batchQueryTopicAudit(res.Data)
					for i, topic := range topicOneAuditVOList {
						topicOneAuditVOList[i].TopicAudit = auditmapOne[topic.TopicId]
						topic.TopicAudit = auditmapOne[topic.TopicId]
					}
					ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_one_list": topicOneAuditVOList, "topic_audit_two_list": ""}})
					return
				} else if utils.StringIsEmpty(projectDO.AuditProjectId) && utils.StringIsNotEmpty(projectDO.FinalProjectId) {
					//只有二审有内容
					topicTwoAuditVOList := batchQueryTopicAnswerVO(projectDO.FinalProjectId, res.Data)
					auditmapTwo := batchQueryTopicAudit(res.Data)
					for i, topic := range topicTwoAuditVOList {
						topicTwoAuditVOList[i].TopicAudit = auditmapTwo[topic.TopicId]
						topic.TopicAudit = auditmapTwo[topic.TopicId]
					}
					ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_one_list": "", "topic_audit_two_list": topicTwoAuditVOList}})
					return
				}
			}
			/*// 查询二审审核内容
			if utils.StringIsNotEmpty(projectDO.FinalProjectId) {
				topicAuditVOList := batchQueryTopicAnswerVO(projectDO.FinalProjectId, res.Data)
				auditmap := batchQueryTopicAudit(res.Data)
				for i, topic := range topicAuditVOList {
					topicAuditVOList[i].TopicAudit = auditmap[topic.TopicId]
					topic.TopicAudit = auditmap[topic.TopicId]
				}
				ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_list": topicAuditVOList}})
				return
			}*/

			//ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res.Data})
			return
		}
		//返修后一审审核视角
		if projectDO.EnumType == modelbase.AuditProj {
			// 查询一审信息
			topicAuditVOList := batchQueryTopicAnswerVO(projectDO.ProjectId, res.Data)
			// 查询作答信息
			topicVOList := batchQueryTopicAnswerVO(projectDO.WorkProjectId, res.Data)
			ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_list": topicAuditVOList}})
			return
		}
		//返修后二审审核视角
		if projectDO.EnumType == modelbase.FinalProj {
			// 查询二审信息
			topicTwoAuditVOList := batchQueryTopicAnswerVO(projectDO.ProjectId, res.Data)
			// 查询一审信息
			topicOneAuditVOList := batchQueryTopicAnswerVO(projectDO.AuditProjectId, res.Data)
			// 查询作答信息
			topicVOList := batchQueryTopicAnswerVO(projectDO.WorkProjectId, res.Data)
			ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"topic_list": topicVOList, "topic_audit_one_list": topicOneAuditVOList, "topic_audit_two_list": topicTwoAuditVOList}})
			return
		}
		/*// 查询原题以及作答
		topicVOList := batchQueryTopicAnswerVO(projectDO.WorkProjectId, res.Data)
		// 查询题目审核
		auditmap := batchQueryTopicAudit(res.Data)
		for _, topic := range topicVOList {
			topic.TopicAudit = auditmap[topic.TopicId]
		}
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: topicVOList})*/
		return
	}
}

// 查询题目审核
func batchQueryTopicAudit(topicList []dao.SystemTopic) map[string]dao.TopicAudit {
	// 查询审核用户
	usermap := batchTopicAuditUser(topicList)
	// 查询审核结果
	ansmap := batchQueryTopicAnswer(topicList)
	// 聚合
	auditmap := make(map[string]dao.TopicAudit, 0)
	for _, topic := range topicList {
		auditmap[topic.TopicId] = dao.TopicAudit{
			AuditUser:   usermap[topic.ReceiverId],
			AuditAnswer: ansmap[topic.Id],
			FinishTime:  topic.FinishTime,
		}
	}
	return auditmap
}

// 查询答主信息
func batchTopicAuditUser(topics []dao.SystemTopic) map[string]dao.TopicUser {
	if len(topics) == 0 {
		return map[string]dao.TopicUser{}
	}
	var uids []string
	for _, topic := range topics {
		uids = append(uids, topic.ReceiverId)
	}
	var userDao dao.Common[dao.SystemUser]
	userList, err := userDao.FindAll(map[string]interface{}{"user_id": uids})
	if err != nil {
		glog.Errorf("batchQueryAnswerUser db.FindAll error: %v", err)
		return nil
	}
	// key -> 用户ID, value -> 答主
	umap := make(map[string]dao.TopicUser, 0)
	for _, u := range userList {
		umap[u.UserId] = dao.TopicUser{
			UserId:     u.UserId,
			RealName:   u.RealName,
			TeamNumber: u.TeamNumber,
			NickName:   u.NickName,
		}
	}
	return umap
}

// 查询答主内容
func batchQueryTopicAnswer(topics []dao.SystemTopic) map[uint][]dao.TopicAnswer {
	if len(topics) == 0 {
		return map[uint][]dao.TopicAnswer{}
	}
	var configIds []uint
	for _, topic := range topics {
		for _, configuration := range topic.TopicConfiguration {
			configIds = append(configIds, configuration.Id)
		}
	}
	var answerDao dao.Common[dao.TopicAnswer]
	ansList, err := answerDao.FindAll(map[string]interface{}{"topic_configuration_id": configIds})
	if err != nil {
		glog.Errorf("batchQueryTopicAnswer db.FindAll error: %v", err)
		return map[uint][]dao.TopicAnswer{}
	}
	// key -> topic_configuration_id, v -> answer
	var cfgansmap = make(map[uint]dao.TopicAnswer, 0)
	for _, answer := range ansList {
		// 取最新一条
		cfgansmap[answer.TopicConfigurationId] = answer
	}
	// key -> 题目ID, v -> 题目作答
	topicansmap := make(map[uint][]dao.TopicAnswer, 0)
	for _, ans := range cfgansmap {
		if _, ok := topicansmap[ans.SystemTopicId]; ok {
			topicansmap[ans.SystemTopicId] = append(topicansmap[ans.SystemTopicId], ans)
		} else {
			topicansmap[ans.SystemTopicId] = []dao.TopicAnswer{ans}
		}
	}
	return topicansmap
}

type SubmitRecordRequest struct {
	Page        int64  `json:"page"`
	PageSize    int64  `json:"page_size"`
	ProjectId   string `json:"project_id"`
	AuditStatus int    `json:"audit_status"` // 审核状态：0:待审核 1:一审通过 2:二审通过
}

// @Summary 提交记录
// @Description 作答的提交记录
// @Tags 题目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body SubmitRecordRequest true "提交记录参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/topic/submit_record/list [post]
func SubmitRecordHandler(ctx iris.Context) {
	var RequestParams SubmitRecordRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	type TopicUserRecord struct {
		dao.TopicUserRecord
		CreatedDateTime time.Time `json:"created_date_time"`
		SN              int       `json:"SN"`
		Title           string    `json:"title"`
	}
	var recordServe services.CommonService[TopicUserRecord]
	recordServe.Page = RequestParams.Page
	recordServe.PageSize = RequestParams.PageSize

	recordServe.Query = map[string]interface{}{"tas_topic_user_record.project_id": RequestParams.ProjectId, "tp": 2, "tas_topic_user_record.user_id": claims.UserName}
	field := fmt.Sprintf("tas_topic_user_record.*,tas_topic_user_record.created_at as created_date_time,title,sn")
	recordServe.SelectField = &field
	//查询当前时间 前180天的数据
	recordServe.WhereStr = append(recordServe.WhereStr, fmt.Sprintf("tas_system_topic.audit_status = %d AND tas_topic_user_record.created_at > '%v'", RequestParams.AuditStatus, time.Now().AddDate(0, 0, -180).Format(timehandler.FormatLayoutTime)))
	recordServe.LeftJoin = append(recordServe.LeftJoin, fmt.Sprintf("left join tas_system_topic on tas_system_topic.id = tas_topic_user_record.system_topic_id"))
	recordServe.Order = fmt.Sprintf("created_at desc")
	if res, err := recordServe.SelectList(); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"count": res.Total, "list": res.Data}})
		return
	}
}

type SubmitAnswerRequest struct {
	Audit         int    `json:"audit"`        // 审核：1:通过 2:不通过
	AddLimit      uint   `json:"add_limit"`    //领取与放弃上限增加
	RemoveLimit   uint   `json:"remove_limit"` //领取与放弃上限减少
	UserId        string `json:"user_id"`      //用户ID
	RejectTime    int    `json:"reject_time"`  // 驳回时间，时间戳，单位：秒
	TopicId       string `json:"topic_id"`
	SystemTopicId uint   `json:"system_topic_id"`
	ProjectId     string `json:"project_id"`
	Tp            int    `json:"tp"` //提交答案类型 1 正常提交答案 2 返修时候提交答案
	Answer        []struct {
		Id         uint   `json:"id"`      //配置Id
		Content    string `json:"content"` //答题答案
		Tp         int    `json:"tp"`      //答题类型 0 文本 1 文件
		AnswerSize int64  `json:"answer_size"`
		FileUrl    string `json:"file_url"` //文件路径
	} `json:"answer"`
}

// @Summary 提交答案
// @Description 提交答案
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body SubmitAnswerRequest true "提交答案参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/topic/submit_answer [post]
func SubmitAnswerHandler(ctx iris.Context) {
	var RequestParams SubmitAnswerRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var topicAnswer []dao.TopicAnswer
	for _, a := range RequestParams.Answer {
		if a.Tp == 1 {
			//split := strings.Split(a.Content, "?uploadId")
			//a.Content = split[0]
			//a.Content, _ = url.QueryUnescape(split[0])
			//fmt.Println(unescape)
		}
		topicAnswer = append(topicAnswer, dao.TopicAnswer{
			TopicId:              RequestParams.TopicId,
			SystemTopicId:        RequestParams.SystemTopicId,
			ProjectId:            RequestParams.ProjectId,
			TopicConfigurationId: a.Id,
			Tp:                   a.Tp,
			Content:              a.Content,
			AnswerSize:           a.AnswerSize,
			UserId:               claims.UserName,
			FileUrl:              a.FileUrl,
		})
	}

	var topicServe services.TopicService
	//增加/减少用户领题上下限
	if RequestParams.Audit > 0 && utils.StringIsNotEmpty(RequestParams.UserId) {
		if err := topicServe.AddOrRemoveUserTopicLimit(RequestParams.UserId, RequestParams.ProjectId, RequestParams.AddLimit, RequestParams.RemoveLimit); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
	}

	if err := topicServe.SubmitAnswer(topicAnswer, RequestParams.Tp, RequestParams.Audit, RequestParams.RejectTime); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

func QueryUserChangeTopicMsgHandler(ctx iris.Context) {
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	messages, err := redis.RedisGClient.SMembers(fmt.Sprintf("UnreadMessages_%d", claims.Id)).Result()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	redis.RedisGClient.Del(fmt.Sprintf("UnreadMessages_%d", claims.Id))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: messages})
	return
}
